#pragma once

#include "Task.hpp"
#include "ThreadPool.hpp"
#include "log.hpp"
#include <iostream>
#include <string>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include <signal.h>
#include <pthread.h>


const int gbacklog = 5;
enum
{
    USAGE_ERR = 1,
    SOCKET_ERR,
    BIND_ERR,
    LISTEN_ERR,
};
class tcpServer
{
public:
    tcpServer(uint16_t port) : _port(port)
    {
    }

    void initServer()
    {
        // 1.创建套接字
        _listensockfd = socket(AF_INET, SOCK_STREAM, 0); // tcp是字节流传输的
        if (_listensockfd < 0)
        {
            logMessage(FATAL, "Create socket failed");
            exit(SOCKET_ERR);
        }
        logMessage(NORMAL, "Create socket success");

        // 2.bind套接字
        struct sockaddr_in server;
        server.sin_family = AF_INET;
        server.sin_port = htons(_port);
        server.sin_addr.s_addr = INADDR_ANY;
        if (bind(_listensockfd, (struct sockaddr *)&server, sizeof(server)) < 0)
        {
            logMessage(FATAL, "Bind failed");
            exit(BIND_ERR);
        }
        logMessage(NORMAL, "Bind success");

        // 3.listen 监听连接
        if (listen(_listensockfd, gbacklog) < 0)
        {
            logMessage(FATAL, "Listen failed");
            exit(LISTEN_ERR);
        }
        logMessage(NORMAL, "Listenning...");
    }

    void start()
    {
        // //version 3 设置信号
        // signal(SIGCLD, SIG_IGN);

        //version 4 初始化线程池
        ThreadPool<Task>::getInstance().run();
        for (;;)
        {
            // 4.获取新连接
            struct sockaddr_in peer;
            socklen_t len = sizeof(peer);
            int sockfd = accept(_listensockfd, (struct sockaddr *)&peer, &len);
            if (sockfd < 0)
            {
                logMessage(ERROR, "Accept failed, next");
                continue;
            }
            logMessage(NORMAL, "accept sock success,sock: %d", sockfd);

            // 5.server与新连接进行通信
            // //version 1
            // Task t(sockfd, ServiceIo);
            // t();


            //version 2(多进程)
            // //1)双fork解决僵尸，用孤儿进程执行任务
            // pid_t id = fork();
            // if(id == 0)
            // {
            //     close(_listensockfd);
            //     if(fork() > 0)exit(0);
            //     Task t(sockfd, ServiceIo);
            //     t();
            //     exit(0);
            // }
            // close(sockfd);

            // int ret = waitpid(id, nullptr, 0);
            // if(ret > 0) std::cout << "wait success" << std::endl;

            // //2）用signal无需等待子进程
            // pid_t id = fork();
            // if(id == 0)
            // {
            //     close(_listensockfd);
            //     Task t(sockfd, ServiceIo);
            //     t();
            //     exit(0);
            // }
            // close(sockfd);

            //version 3(多线程)
            // pthread_t pid;
            // pthread_create(&pid, nullptr, service_routine, (void*)&sockfd);

            //version 4(线程池)
            ThreadPool<Task>::getInstance().push(Task(sockfd, ServiceIo));
        }

    }
    static void* service_routine(void* args)
    {
        int sockfd = *static_cast<int*>(args);
        Task t(sockfd, ServiceIo);
        t();
        
        return nullptr;
    }


    ~tcpServer()
    {
    }

private:
    int _listensockfd;
    uint16_t _port;
};